package managed.bean;

import com.marlboroug.admins.AdminsManagerRemote;
import com.marlboroug.entity.Admins;
import java.io.IOException;
import java.io.Serializable;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.List;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;

/**
 * Gestion de l'espace de connexion.
 *
 * @author Cyril Schumacher
 */
@ManagedBean
@SessionScoped
public class AccountLogin implements Serializable {
    // <editor-fold defaultstate="collapsed" desc="Constantes.">
    /**
     * Grain de sel pour le mot de passe.
     */
    private final static String _SALT_PASSWORD = "booxtore";
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Membres.">
    /**
     * Gestion des identifiants.
     */
    @EJB
    private AdminsManagerRemote _adminsManager;
    /**
     * Nom d'identifiant.
     */
    private String username;
    /**
     * Mot de passe.
     */
    private String password;
    /**
     * Est connecté.
     */
    private Boolean isLogged;
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Accesseurs/Mutateurs.">
    /**
     * Obtient le nom d'utilisateur.
     *
     * @return Retourne un nom d'utilisateur.
     */
    public String getUsername() {
        return username;
    }

    /**
     * Définit le nom d'utilisateur.
     *
     * @param username Nom d'utilisateur.
     */
    public void setUsername(String username) {
        this.username = username;
    }

    /**
     * Obtient le mot de passe.
     *
     * @return Retourne un mot de passe.
     */
    public String getPassword() {
        return password;
    }

    /**
     * Définit le mot de passe.
     *
     * @param password Mot de passe.
     */
    public void setPassword(String password) {
        this.password = password;
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Méthodes.">
    // <editor-fold defaultstate="collapsed" desc="Privées.">
    /**
     * Détermine si le nom d'utilisateur et le mot de passe sont valides.
     *
     * @return Retourne TRUE si le nom d'utilisateur et le mot de passe sont
     * valides, FALSE sinon.
     */
    private Boolean _checkUsernamePassword() throws NoSuchAlgorithmException {
        // Recherche le nom d'utilisateur.
        List<Admins> usernameFound = _adminsManager.AuthentificationPseudo(username);
        if (usernameFound.size() == 1) {
            // Récupère l'identifiant selon le nom d'utilisateur.
            long usernameId = usernameFound.get(0).getIDadmins();

            // Récupère le mot de passe de l'utilisateur.
            String passwordWithSalt = password + _SALT_PASSWORD;
            password = _cryptPassword(passwordWithSalt);

            List<Admins> passwordFound = _adminsManager.AuthentificationPassword(password);
            if (passwordFound.size() == 1) {
                return true;
            }
        }

        // Si l'utilisateur n'a pas pu être créer, on signale l'erreur à 
        // l'utilisateur.
        FacesContext.getCurrentInstance().addMessage("id", new FacesMessage(FacesMessage.SEVERITY_ERROR,
                "Le nom d'utilisateur ou le mot de passe est incorrect.", null));
        return false;
    }

    /**
     * Crypte le mot de passe.
     *
     * @param password Mot de passe.
     * @return Retourne le mot de passe crypté.
     * @throws NoSuchAlgorithmException
     */
    public String _cryptPassword(String password) throws NoSuchAlgorithmException {
        MessageDigest messageDigest = MessageDigest.getInstance("MD5");
        messageDigest.update(password.getBytes());
        byte[] passwordBytes = messageDigest.digest();

        StringBuilder buffer = new StringBuilder();
        for (byte b : passwordBytes) {
            buffer.append(Integer.toHexString((int) (b & 0xff)));
        }

        return buffer.toString();
    }

    // </editor-fold>
    /**
     * Connecte l'utilisateur.
     *
     * @return Retourne "success" si l'utilisateur est authentifié, "failure"
     * sinon.
     * @throws java.security.NoSuchAlgorithmException
     */
    public String login() throws NoSuchAlgorithmException {
        if (_checkUsernamePassword()) {
            // Indique que l'utilisateur est connecté.
            isLogged = true;
            return "success";
        } else {
            return "failure";
        }
    }

    /**
     * Redirige l'utilisateur si celui-ci est connecté.
     *
     * @throws IOException
     */
    public void logout() throws IOException {
        if (isLogged == true) {
            FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
            ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
            context.redirect("login.xhtml");
        }
    }

    /**
     * Redirige l'utilisateur si celui-ci est connecté.
     *
     * @throws IOException
     */
    public void isLogged() throws IOException {
        if (isLogged == true) {
            ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
            context.redirect("index.xhtml");
        }
    }

    /**
     * Redirige l'utilisateur si celui-ci n'est pas connecté.
     *
     * @throws IOException
     */
    public void isNotLogged() throws IOException {
        if (isLogged == false) {
            ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
            context.redirect("faces/login.xhtml");
        }
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Constructeur.">
    /**
     * Constructeur.
     */
    public AccountLogin() {
        // Par défaut, l'utilisateur est deconnecté.
        isLogged = false;
    }
    // </editor-fold>
}
